package Graph;

import GraphCore.GraphInterface;
import java.util.HashMap;
import java.util.Map;


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author rodacki, Tiago,Ruan
 * Objeto que representa o Grafo.
 */
public class Graph implements GraphInterface {
    private Map<Integer, Vertex> vertexes = new HashMap();
    
    /**
     * 
     * Ordem do Grafo 
     */
    @Override
    public int getOrder() {
        return getVertexes().size();
    }

    /**
     * 
     * Tamanho do Grafo 
     */
    @Override
    public int getSize() {
        int count = 0;
        for (Map.Entry<Integer, Vertex> entry : vertexes.entrySet()) {
            Integer integer = entry.getKey();
            Vertex vertex = entry.getValue();
            count = vertex.getDegree() + count;
        } 
        count = count/2; 
        return count;
    }
    
    /**
     * 
     * V 
     */
    @Override
    public int V() {
        return getOrder();
    }

    /**
     * 
     * E 
     */
    @Override
    public int E() {
        return getSize();
    }

    /**
     * 
     * Adiciona Vertice passando por parametro um id.
     */
    @Override
    public void addVertex(int id) {
            getVertexes().put(id, new Vertex(id));
    }

    /**
     * Adiciona Aresta passando por parametro 2 vertices.
     */
    @Override
    public void addEdge(Vertex vi, Vertex vj, int cost) {     
        vi.getEdges().add(new Edge(vi, vj, cost));
        vj.getEdges().add(new Edge(vj, vi, cost));
        vi.adj();
        vj.adj();
        vi.setDegree(vi.getDegree()+1);
        vj.setDegree(vj.getDegree()+1);
    }

    /**
     * Método que retorna se 2 vertices passados por parametro são adjacentes.
     */
    @Override
    public boolean adjacent(Vertex vi, Vertex vj) {
        if(vi.isAdjacent(vj))
            return true;
        return false;
    }

    /**
     * Remove Vertice passando por parametro um id.
     */
    @Override
    public void removeVertex(int id) {
        for(int i=0; i < getVertexes().get(id).getEdges().size();i++){
                    removeEdge(getVertexes().get(id).getEdges().get(i).getVj(), getVertexes().get(id));
        }   
        getVertexes().remove(id);
    }

    /**
     * Remove Aresta passando por parametro 2 vertices.
     */
    @Override
    public void removeEdge(Vertex vi, Vertex vj) {
        for(int i=0;i<vi.getEdges().size();i++){
            if(vi.getEdges().get(i).getVi().isAdjacent(vj))
                vi.getEdges().remove(i);
                vi.setDegree(vi.getDegree()-1);         
        }
        for(int i=0;i<vj.getEdges().size();i++){
            if(vj.getEdges().get(i).getVj().isAdjacent(vi))
                vj.getEdges().remove(i);
                vj.setDegree(vj.getDegree()-1);
        }
            
    }

    /**
     * @return the vertexes
     */
    public Map<Integer, Vertex> getVertexes() {
        return vertexes;
    }

    /**
     * @param vertexes the vertexes to set
     */
    public void setVertexes(HashMap<Integer, Vertex> vertexes) {
        this.vertexes = vertexes;
    }

    /**
     * ToString do Grapho
     */
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("Graph \n { vertexes=");
        sb.append(vertexes.toString());
        sb.append("}");
        return sb.toString();
    }

}